/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Serial;

import slisfx.Globals;

/**
 *
 * @author Everett
 */
public class X10Handler implements Globals {
    
    private static byte[] houseCode = {96, (byte) 224, 32, (byte) 160, 16, 
        (byte)144, 80, (byte) 208, 112, (byte) 240, 48, (byte) 176, 0, 
        (byte) 128, 64, (byte) 192};
    private static byte[] deviceCode = {6, 14, 2, 10, 1, 9, 5, 13, 7, 15, 3, 11,
        0, 8, 4, 12};
    private static byte[] part1x10 = new byte[4];
    private static byte[] part2x10 = new byte[4];
    
    private static byte[] command = new byte[11];
    private static final int ringBuffSize = 1024;
    private static byte[] ringBuffer = new byte[ringBuffSize];
    private static int startBuff;
    private static int endBuff;
    
    private static int alarmState;
    private static int ambTemp;
    private static int setTemp;
    
    public X10Handler()
    {
        
    }
    
    public void init()
    {
        part1x10[0] = 2;
        part1x10[1] = 99;
        part1x10[3] = 0;
        part2x10[0] = 2;
        part2x10[1] = 99;
        part2x10[3] = (byte) 128;
        startBuff=0;
        endBuff=0;
        alarmState=0;
        ambTemp=75;
        setTemp=75;
    }
    
    public void x10on(char house, int device)
    {
        part1x10[2] = (byte) (houseCode[houseToInt(house)] + deviceCode[device-1]);
        part2x10[2] = (byte) (houseCode[houseToInt(house)] + 2);
        
        System.out.println("a "+part1x10[0]);
        plm.write(part1x10);
        delay(500);
        plm.write(part2x10);
        delay(500);
    }
    
    public void x10off(char house, int device)
    {
        part1x10[2] = (byte) (houseCode[houseToInt(house)] + deviceCode[device-1]);
        part2x10[2] = (byte) (houseCode[houseToInt(house)] + 3);
        plm.write(part1x10);
        delay(500);
        plm.write(part2x10);
        delay(500);
    }
    
    public void x10dim(char house, int device)
    {
        part1x10[2] = (byte) (houseCode[houseToInt(house)] + deviceCode[device-1]);
        part2x10[2] = (byte) (houseCode[houseToInt(house)] + 4);
        plm.write(part1x10);
        delay(500);
        plm.write(part2x10);
        delay(500);
    }
    
    public void x10brighten(char house, int device)
    {
        part1x10[2] = (byte) (houseCode[houseToInt(house)] + deviceCode[device-1]);
        part2x10[2] = (byte) (houseCode[houseToInt(house)] + 5);
        plm.write(part1x10);
        delay(500);
        plm.write(part2x10);
        delay(500);
    }
    
    public void thermo (int code)
    {
        // 1 = heat, 2 = cool, 3 = off, 4 = +temp, 5=-temp, 6=getcurrtemp, 7 = getset
        byte thermCommand[]={2,98,0x14,(byte)0x92,(byte)0x3c,15,0,0};
        switch(code)
        {
            case 1: thermCommand[6]=107;
                    thermCommand[7]=0x04;
        System.out.println("therno");
                    break;
            case 2: thermCommand[6]=107;
                    thermCommand[7]=0x05;
                    break;
            case 3: thermCommand[6]=107;
                    thermCommand[7]=0x09;
                    break;
            case 4: thermCommand[6]=104;
                    thermCommand[7]=0x02;
                    break;
            case 5: thermCommand[6]=105;
                    thermCommand[7]=0x02;
                    break;
            case 6: thermCommand[6]=107;
                    thermCommand[7]=0x03;
                    break;
            case 7: thermCommand[6]=106;
                    thermCommand[7]=0x22;
                    break;
        }
        plm.write(thermCommand);
        System.out.println("therno");
    }
    
    public void plmHandler (byte in[])
    {
        readIntoBuff(in);
        
        while(getCurSize()>=11)
        {
            getChunk();
            
            if(command[3] ==(byte)0x7E && command[4] == (byte)0xD0)
            {
                if(command[9]==(byte)0x11)
                {
                    System.out.println("Motion senor sensed you");
                    if(alarmState==2)
                    {
                        delay(1000);
                        x10on('E',2);
                        delay(1000);
                        x10off('E',2);
//                        delay(500);
//                        x10on('E',2);
                    }
                }
                else if(command[9]==(byte)0x13)
                    System.out.println("No more motion");
            }
            else if(command[3] == (byte)0x8F && command[4] == (byte)0x1E)
            {
                if(command[9]==(byte)0x11)
                {
                    System.out.println("A is apart");
                    if(alarmState==1 || alarmState==2)
                    {
                        delay(1000);
                        x10on('E',3);
                        delay(1000);
                        x10off('E',3);
//                        delay(500);
//                        x10on('E',3);
                    }
                }
                else if(command[9]==(byte)0x13)
                    System.out.println("A is together blah");
            }
            else if(command[3] == (byte)0x90 && command[4] == (byte)0x51)
            {
                if(command[9]==(byte)0x11)
                {
                    System.out.println("B is apart");
                    if(alarmState==1 || alarmState==2)
                    {
                        delay(1000);
                        x10on('E',4);
                        delay(1000);
                        x10off('E',4);
//                        delay(500);
//                        x10on('E',4);
                    }
                }
                else if(command[9]==(byte)0x13)
                {
                    System.out.println("B is together");
                    
                }
            }
            
            else if(command[2]==0x14 && command[3]==(byte)0x92)
            {
                if(command[9]==0x6b && (command[10]&0xff)>25)
                {
                    ambTemp=(command[10]&0xff)/2;
                    System.out.println("Room temp is " + ambTemp);
                }
                else if (command[9]==106)
                {
                    setTemp=(command[10]&0xff)/2;
                    System.out.println("Set temp is " + setTemp);
                }
            }
            
            else{
                for(int j =0;j<command.length;j++){
                       System.out.print(Integer.toHexString(command[j]&0xFF)+" ");}
                       System.out.println("Not found");
            }
        }
        
        
        
    }
    private void getChunk()
    {
        for(int i = 0; i<11; i++)
        {
            command[i]=ringBuffer[startBuff];
            startBuff++;
            if(startBuff>=ringBuffSize)
                startBuff=0;
            if (/*i==8 && command[8]==6*/ command[i]==6)
            {
                System.out.println("GET ME OUT OF HERE");
                break; 
            }
        }
    }
    
    private int getCurSize()
    {
        if(endBuff>=startBuff)
            return endBuff-startBuff;
        else return endBuff+ringBuffSize-startBuff;
    }
    
    private void readIntoBuff(byte in[])
    {
        for (int i = 0;i<in.length;i++)
        {
            ringBuffer[endBuff]=in[i];
            endBuff++;
            if(endBuff>=ringBuffSize)
                endBuff=0;
        }
    }
    
    public void setAlarmState(int state)
    {
        alarmState=state;
    }
    
    public int getAlarmState()
    {
        return alarmState;
    }
    
    public int getRoomTemp()
    {
        thermo(6);
        delay(500);
        return ambTemp;
    }
    
    public int getSetTemp()
    {
        delay(400);
        thermo(7);
        delay(500);
        return setTemp;
    }
    
    private int houseToInt(char house)
    {
        int houseAsNum=16;
        switch(house){
            case 'A': houseAsNum=0;
                    break;
            case 'B': houseAsNum=1;
                    break;
            case 'C': houseAsNum=2;
                    break;
            case 'D': houseAsNum=3;
                    break;
            case 'E': houseAsNum=4;
                    break;
            case 'F': houseAsNum=5;
                    break;
            case 'G': houseAsNum=6;
                    break;
            case 'H': houseAsNum=7;
                    break;
            case 'I': houseAsNum=8;
                    break;
            case 'J': houseAsNum=9;
                    break;
            case 'K': houseAsNum=10;
                    break;
            case 'L': houseAsNum=11;
                    break;
            case 'M': houseAsNum=12;
                    break;
            case 'N': houseAsNum=13;
                    break;
            case 'O': houseAsNum=14;
                    break;
            case 'P': houseAsNum=15;
                    break;
        }
        return houseAsNum;
                
    }
    
    private void delay(int time)
    {
        try {
            Thread.sleep(time); 
        } catch (Exception e) {}
    }
    
}
